package de.mmis.core.base.abstracttree.serializer.internal;

import java.util.Map;

import de.mmis.core.base.DeserializableAnnotations.DeserializationMethod;
import de.mmis.core.base.Toolbox;
import de.mmis.core.base.abstracttree.InnerNode;
import de.mmis.core.base.abstracttree.LeafNode;
import de.mmis.core.base.abstracttree.LeafNode.Encoding;
import de.mmis.core.base.abstracttree.Tree;
import de.mmis.core.base.abstracttree.Tree.Type;
import de.mmis.core.base.abstracttree.serializer.AbstractSerializer;
import de.mmis.core.base.abstracttree.serializer.DeserializableException;

/**
 * Serializer class for (de)serializing short integer from/to Trees
 * 
 * @author Christian Koch
 */
public class ClassSerializer extends AbstractSerializer<Class<?>> {

	@DeserializationMethod
	public static Object deserialize(Tree[] exps, ClassLoader classLoader,
			String id, Map<String, Object> idmap)
			throws DeserializableException {

		if (exps.length != 1)
			throw new DeserializableException(new InnerNode(exps),
					"Class Tree needs 1 parameter");

		if (exps[0].getType() != Type.LEAF
				|| (((LeafNode) exps[0]).getEncoding() != Encoding.Quoted && ((LeafNode) exps[0])
						.getEncoding() != Encoding.Token))
			throw new DeserializableException(new InnerNode(exps),
					"Class Tree is no token or quoted atom");

		return getAtomClass((LeafNode) exps[0], classLoader);
	}

	public static Class<?> getAtomClass(LeafNode exp, ClassLoader classLoader)
			throws DeserializableException {
		String classString = exp.getUTF8Data();
		try {
			return Toolbox.forName(classString, classLoader);
		} catch (ClassNotFoundException e) {
			throw new DeserializableException(exp, e, "class " + classString
					+ " cannot be loaded");
		}
	}

	@Override
	public Tree serializeInternal(Class<?> object, boolean explicit,
			Map<Object, String> refmap, ClassLoader classLoader) {
		return new LeafNode(object.getName());
	}

	@Override
	public String getTypeIdentifier() {
		return "java-class";
	}
}
